import logging
import time
import pytest
from common.request_util_test import RequestUtil
from common.test_yaml_util_test import YamlUtil
from common.read_values import TextUtil
from config import datas
from common.extension_component import ExtensionComponent, InstallationParams


class TestColocationManagement():
    flag_installed_stat = 0  # flag置0表示colocation-package之前未安装，需要在本测试套临时安装。置1表示之前已安装，无需安装
    url_verify = "/clusters/host/rest/colocation/v1/colocation-configs"

    @pytest.mark.normal
    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('valuesinfo',
                             TextUtil().read_value_yaml('values_colocation.yaml'))
    def test_install_colocation(self, valuesinfo):
        res = ExtensionComponent.is_installed('colocation')
        if res == False:
            # 安装并检查
            uri_install = "/rest/application-management/v1beta1/helm-releases/namespace/{namespace}/release/{release}"
            uri_install = uri_install.replace("{namespace}", datas.test_colocation["namespace"])
            uri_install = uri_install.replace("{release}", datas.test_colocation["release"])
            url_install = datas.baseUrl + uri_install
            method_install = "POST"
            headers_install = {"Content-Type": "application/json"}
            data_install = {
                "chartName": datas.test_colocation["release"],
                "repoName": datas.test_colocation["repoName"],
                "version": datas.test_colocation["version"],
                "values": valuesinfo["data"],
            }
            params = InstallationParams(url_install, method_install, headers_install, data_install)
            res_install = ExtensionComponent.installing(params, datas.baseUrl + self.url_verify)
            assert res_install == True

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/1_get_colocation_configs.yaml'))
    def test_get_colocation_configs(self, colocationinfo):
        # 查询混部全部配置-正常
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        globals()['nodeInfo'] = req.json()['data']['nodeInfo']
        globals()['nodename'] = req.json()['data']['nodeInfo'][0]['name']
        logging.debug(req.json())
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/1_get_colocation_configs_exception.yaml'))
    def test_get_colocation_configs_exception(self, colocationinfo):
        # 查询混部全部配置-异常
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/2_open_colocation_nodes.yaml'))
    def test_open_colocation_nodes(self, colocationinfo):
        # 打开混部节点开关-正常
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        method = colocationinfo['request']['method']
        header = colocationinfo['request']['header']
        req = RequestUtil().send_request(method, url, headers=header)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/2_open_colocation_nodes_exception.yaml'))
    def test_open_colocation_nodes_exception(self, colocationinfo):
        # 打开混部节点开关-异常
        base_url = datas.baseUrl
        if 'nodename为空' not in colocationinfo['name']:
            url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        else:
            url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        header = colocationinfo['request']['header']
        req = RequestUtil().send_request(method, url, headers=header)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/3_modify_colocation_configs.yaml'))
    def test_modify_colocation_configs(self, colocationinfo):
        # 修改混部调度、驱逐配置接口-正常
        time.sleep(5)
        TestColocationManagement.test_get_colocation_configs
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        colocationinfo['request']['data']['nodeInfo'] = globals()['nodeInfo']
        data = colocationinfo['request']['data']
        req = RequestUtil().send_request(method, url, json=data)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo', YamlUtil().read_testcase_yaml(
        'v25.06/colocation/3_modify_colocation_configs_exception.yaml'))
    def test_modify_colocation_configs_exception(self, colocationinfo):
        # 修改混部调度、驱逐配置接口-异常
        TestColocationManagement.test_get_colocation_configs
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        colocationinfo['request']['data']['nodeInfo'] = globals()['nodeInfo']
        data = colocationinfo['request']['data']
        req = RequestUtil().send_request(method, url, json=data)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/5_get_colocation_status.yaml'))
    def test_get_colocation_status(self, colocationinfo):
        # 获取全量混部节点、混部负载-正常
        logging.debug(colocationinfo['name'])
        time.sleep(5)
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        logging.debug(req.json())
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/5_get_colocation_status_exception.yaml'))
    def test_get_colocation_status_exception(self, colocationinfo):
        # 获取全量混部节点、混部负载-异常
        logging.debug(colocationinfo['name'])
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/6_get_colocation_metrics_cluster.yaml'))
    def test_get_colocation_metrics_cluster(self, colocationinfo):
        # 获取集群监控折线图-正常
        logging.debug(colocationinfo['name'])
        time.sleep(5)
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        logging.debug(req.json())
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo', YamlUtil().read_testcase_yaml(
        'v25.06/colocation/6_get_colocation_metrics_cluster_exception.yaml'))
    def test_get_colocation_metrics_cluster_exception(self, colocationinfo):
        # 获取集群监控折线图-异常
        logging.debug(colocationinfo['name'])
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/7_get_colocation_metrics_nodes.yaml'))
    def test_get_colocation_metrics_nodes(self, colocationinfo):
        # 获取节点监控折线图-正常
        logging.debug(colocationinfo['name'])
        time.sleep(5)
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        logging.debug(req.json())
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo', YamlUtil().read_testcase_yaml(
        'v25.06/colocation/7_get_colocation_metrics_nodes_exception.yaml'))
    def test_get_colocation_metrics_nodes_exception(self, colocationinfo):
        # 获取节点监控折线图-异常
        logging.debug(colocationinfo['name'])
        base_url = datas.baseUrl
        if 'nodename为空' not in colocationinfo['name']:
            url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        else:
            url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        req = RequestUtil().send_request(method, url)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/4_close_colocation_nodes.yaml'))
    def test_close_colocation_nodes(self, colocationinfo):
        # 关闭混部节点开关-正常
        logging.debug(colocationinfo['name'])
        base_url = datas.baseUrl
        url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        method = colocationinfo['request']['method']
        header = colocationinfo['request']['header']
        req = RequestUtil().send_request(method, url, headers=header)
        logging.debug(req.json())
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.abnormal
    @pytest.mark.colocation
    @pytest.mark.parametrize('colocationinfo',
                             YamlUtil().read_testcase_yaml('v25.06/colocation/4_close_colocation_nodes_exception.yaml')
                             )
    def test_close_colocation_nodes_excpetion(self, colocationinfo):
        # 关闭混部节点开关-异常
        logging.debug(colocationinfo['name'])
        base_url = datas.baseUrl
        if 'nodename为空' not in colocationinfo['name']:
            url = base_url + colocationinfo['request']['url'].replace('{nodename}', globals()['nodename'])
        else:
            url = base_url + colocationinfo['request']['url']
        method = colocationinfo['request']['method']
        header = colocationinfo['request']['header']
        req = RequestUtil().send_request(method, url, headers=header)
        assert req.status_code == colocationinfo['validate'][0]['equals']['status_code']

    @pytest.mark.normal
    @pytest.mark.abnormal
    @pytest.mark.colocation
    def test_uninstall_colocation(self):
        # 卸载并检查
        uri_delete = ("/clusters/host/rest/application-management/v1beta1/helm-releases/"
                      "namespace/{namespace}/release/{release}")
        uri_delete = uri_delete.replace("{namespace}", datas.test_colocation["namespace"])
        uri_delete = uri_delete.replace("{release}", datas.test_colocation["release"])
        url_delete = datas.baseUrl + uri_delete
        method_delete = "DELETE"
        params = InstallationParams(url_delete, method_delete)
        res_uninstall = ExtensionComponent.uninstall(params, datas.baseUrl + self.url_verify)
        assert res_uninstall == True
